home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / tde.zip / TDE.CPP < prev    next >
C/C++ Source or Header  |  1992-07-14  |  28KB  |  796 lines

  1. /***************************************************************************
  2.  
  3.  FILENAME - TDE.CPP: class TDataEntry definitions
  4.  ------------------
  5.  
  6.  Class TDataEntry v1.0 - 07/14/92
  7.  --------------------------------
  8.  
  9.  ----------------------------------------------------------------------------
  10.  Author: Jeff Penrose * JDP Custom Software * (818) 344-7303 * CIS 71043,3727
  11.  ----------------------------------------------------------------------------
  12.  
  13.  A data entry class for Borland's Turbo Vision, derived from TInputLine.
  14.  
  15.  Copyright Notice
  16.  ================
  17.   As this material is ultimately derived from Borland source files, any of
  18.  their copyrights which MAY apply DO apply.
  19.   From the author's standpoint, you may use this material freely and,
  20.  hopefully, post any comments/corrections/enhancements to me at the above-
  21.  noted addresses.  I do ask that you not distribute this material except as
  22.  originally received, including all source/documentation files in their
  23.  original form.
  24.   If you DO modify or enhance any of this code, please send any such changes
  25.  to me for incorporation into a future version.  Any such enhancements will
  26.  be DONATED, without expectation of compensation or incorporation into
  27.  future versions.  Again, if you distribute this code, please do so in its
  28.  original, unmodified form including all source files and documentation.
  29.  
  30.  Source files included
  31. =====================
  32.  TDE     .DOC: This documentation.
  33.  TDE     .MAN: How to use TDataEntry in your dialog objects
  34.  TDE     .H  : header file containing class declarations for classes
  35.  TDEFLAGS.H  :   "     "      "       flags and command definitions
  36.  TDE     .CPP: Class TDataEntry
  37.  TDEDATE .CPP: Class TDEDate
  38.  TDEPHONE.CPP: Classes TDEPhone, TDEZipCode, TDEState
  39.  TDENUMS .CPP: Class TDEInteger
  40.  TDECLUST.CPP: Non-TDataEntry classes TDEButton, TDERadioButtons, TDECheckBoxes
  41.  TDEINPLI.CPP: Non-TDataEntry class TDEInputLine
  42.  TDELIB  .PRJ: Project for building library TDELIB.LIB
  43.  TDEDEMO .CPP: Demo program
  44.  TDEDEMO .PRJ: Project for building TDEDEMO.EXE
  45.  
  46. ***************************************************************************/
  47.  
  48. #define Uses_TDrawBuffer
  49. #define Uses_TEvent
  50. #define Uses_TInputLine
  51. #define Uses_TKeys
  52. #define Uses_TProgram // TESTING for cmReleasedFocus
  53. #define Uses_TRect
  54. #define Uses_MsgBox
  55. #define Uses_opstream
  56. #define Uses_ipstream
  57. //#include <tv.h>
  58.  
  59. #include "tde.h"
  60.  
  61. #if !defined( __STRING_H )  // for strlen()
  62. #include <String.h>
  63. #endif  // __STRING_H
  64.  
  65. #ifndef __LIMITS_H          // for UCHAR_MAX
  66. #include <limits.h>
  67. #endif
  68.                             // define static members
  69.  
  70. uchar  TDataEntry::globalID        = 0;
  71. ushort TDataEntry::globalMode      = (tdgBeepEnable | tdgSelectOnFocus);
  72. char  *TDataEntry::msgDataRequired = "\003Required data is missing!";
  73. char  *TDataEntry::msgDataInvalid  = "\003Invalid data!";
  74. char   TDataEntry::secureChar      = '#';
  75.  
  76. static Boolean  exitAuto = False;
  77. const int CONTROL_Y = 25;
  78.  
  79. //--------------------------------------------------------------------------
  80. //
  81. // **** TDataEntry::TDataEntry()
  82. //
  83. // CONSTRUCTOR for formatted data entry (usually including punctuation, etc.
  84. //   which cannot be edited by the user).  You MUST use this version if the
  85. //   format includes non-MASK_CHAR's.
  86. //--------------------------------------------------------------------------
  87. TDataEntry::TDataEntry(int col, int row, char *format, const char *fName ) :
  88.             TInputLine(TRect(col, row, col + strlen(format), row + 1), 1),
  89.             tdCurPos( -1 ),
  90.             localMode( tdlRLArrows | tdlInsertEnable ),
  91.             dataFormat( 0 ),
  92.             mask( NULL ),
  93.             outView( NULL ),
  94.             origData( NULL ),
  95.             fieldName( NULL )
  96. {
  97.   int len = strlen(format);
  98.  
  99.   maxLen  = 0;
  100.   mask    = new char[len + 1];
  101.   if ( !mask ) return;
  102.   outView = new char[len + 1];
  103.   if ( !outView ) return;
  104.   strcpy (mask, format);
  105.   for ( int i = 0; i < len; i++ )
  106.   {
  107.     if ( mask[i] == MASK_CHAR )
  108.     {
  109.       outView[i] = ' ';
  110.       ++maxLen;
  111.       tdLastPos = i;
  112.       if ( tdCurPos < 0 ) tdCurPos = firstPos = i;
  113.     }
  114.     else
  115.       outView[i] = mask[i];
  116.   }
  117.   delete data;
  118.   data       = NULL;
  119.   data       = new char[maxLen + 1];
  120.   origData   = new char[maxLen + 1];
  121.   outView[i] = *data = *origData = EOS;
  122.   eventMask |= evBroadcast;
  123.   if ( globalID + 1 > UCHAR_MAX )
  124.     localID = UCHAR_MAX;
  125.   else
  126.     localID = globalID++;
  127.   if ( fName && (fieldName = new char[strlen(fName) + 1]) != NULL )
  128.     strcpy( fieldName, fName );
  129. }
  130.  
  131. //--------------------------------------------------------------------------
  132. //
  133. // **** TDataEntry::TDataEntry()
  134. //
  135. // CONSTRUCTOR for data entry field where format is all MASK char's.  Ie,
  136. //   user can enter data in any position.  Useful when you want something
  137. //   like a long numeric field w/no formatting.  You don't need to type in
  138. //   a string of (say) 40 MASK_CHAR's.  You CANNOT use this version if the
  139. //   format string contains any non-MASK_CHAR's.
  140. //--------------------------------------------------------------------------
  141. TDataEntry::TDataEntry(int col, int row, int len, const char *fName ) :
  142.             TInputLine(TRect(col, row, col + len, row + 1), len + 1 ),
  143.             tdCurPos( 0 ),
  144.             localMode( tdlRLArrows | tdlInsertEnable ),
  145.             dataFormat( 0 ),
  146.             mask( NULL ),
  147.             outView( NULL ),
  148.             origData( NULL ),
  149.             fieldName( NULL )
  150. {
  151.   mask    = new char[len + 1];  // maxLen, data set in base constructor
  152.   if ( !mask ) return;
  153.   outView = new char[len + 1];
  154.   if ( !outView ) return;
  155.   memset(mask, MASK_CHAR, maxLen);
  156.   memset(outView, ' ', maxLen);
  157.   origData   = new char[maxLen + 1];
  158.   if ( !origData ) return;
  159.   mask[maxLen] = outView[maxLen] = *data = *origData = EOS;
  160.   firstPos = 0;
  161.   tdLastPos = len - 1;
  162.   eventMask |= evBroadcast;
  163.   if ( globalID + 1 > UCHAR_MAX )
  164.     localID = UCHAR_MAX;
  165.   else
  166.     localID = globalID++;
  167.   if ( fName && (fieldName = new char[strlen(fName) + 1]) != NULL )
  168.     strcpy( fieldName, fName );
  169. };
  170.  
  171. //--------------------------------------------------------------------------
  172. //
  173. // **** TDataEntry::~TDataEntry()
  174. //
  175. //--------------------------------------------------------------------------
  176. TDataEntry::~TDataEntry()
  177. {
  178.   delete mask;
  179.   delete outView;
  180.   delete origData;
  181.   delete fieldName;
  182. }
  183.  
  184. //--------------------------------------------------------------------------
  185. //
  186. // **** TDataEntry::dataSize()
  187. //
  188. //--------------------------------------------------------------------------
  189. ushort TDataEntry::dataSize()
  190. {
  191.   return maxLen + 1;
  192. }
  193.  
  194. //--------------------------------------------------------------------------
  195. //
  196. // **** TDataEntry::draw()
  197. //
  198. //--------------------------------------------------------------------------
  199. void TDataEntry::draw()
  200. {
  201.   int L, R;
  202.   TDrawBuffer b;
  203.  
  204.   uchar color = (state & sfFocused) ? getColor( 2 ) : getColor( 1 );
  205.  
  206.   b.moveChar( 0, ' ', color, size.x );
  207.   char buf[256];
  208.   formatView();  // ADDED BACK 06/02/92 for THistory to WORK!!!
  209.   strncpy(buf, outView, size.x );
  210.   buf[size.x ] = EOS;
  211.   b.moveStr( 0, buf, color );
  212.   if( (state & sfSelected) != 0 )  // strlen(data) &&
  213.   {
  214.     L = tdSelStart;  // JDP 01/19/92 WAS: l = selStart;  // JDP ... - firstPos
  215.     R = tdSelEnd;    // JDP 01/19/92 WAS: r = selEnd;    // JDP ... - firstPos;
  216.     L = max(firstPos, L );  // JDP 01/21/92 firstPos WAS 0
  217.     R = min( size.x, R );
  218.     if ( L < R )          //* JDP 07/13/92 removed -->  && L + 1 != R
  219.       b.moveChar( L, 0, getColor(3), R - L); // +- 1 );
  220.   }
  221.   writeLine( 0, 0, size.x, size.y, b );
  222.   setCursor( tdCurPos, 0);
  223. }
  224.  
  225. //--------------------------------------------------------------------------
  226. //
  227. // **** TDataEntry::getData()
  228. //
  229. //--------------------------------------------------------------------------
  230. void TDataEntry::getData( void *rec )
  231. {
  232.   // memcpy( rec, data, dataSize() );
  233.   memcpy( rec, data, strlen(data) + 1 );
  234. }
  235.  
  236. //--------------------------------------------------------------------------
  237. //
  238. // **** TDataEntry::mousePos()
  239. //
  240. //--------------------------------------------------------------------------
  241. int TDataEntry::mousePos( TEvent& event )
  242. {
  243.   TPoint mouse = makeLocal( event.mouse.where );
  244.   mouse.x = max( mouse.x, firstPos);   // JDP 01/21/92 firstPos = 0
  245.   int pos = max( mouse.x, firstPos );  // JDP 01/21/92 firstPos = 0
  246.   pos = min( mouse.x, tdLastPos + 1);  // + 1);  //* JDP 01/21/92 tdLastPos = strlen(data) );
  247.   return pos;                      //* JDP 07/13/92 added +1 back in
  248. }
  249.  
  250. //--------------------------------------------------------------------------
  251. //
  252. // **** TDataEntry::deleteSelect()
  253. //
  254. //--------------------------------------------------------------------------
  255. void  TDataEntry::deleteSelect()
  256. {
  257.   if( selStart < selEnd )
  258.   {
  259.     strcpy( data + selStart, data + selEnd); // JDP + 1 );
  260.     curPos = selStart;
  261.     tdCurPos = tdSelStart;  // JDP 01/19/92
  262.     // formatView();           // JDP added 1/18/92; deleted 06/02/92
  263.   }
  264. }
  265.  
  266. //--------------------------------------------------------------------------
  267. //
  268. // **** TDataEntry::setViewPos
  269. //
  270. //  Called every time cursor position must change.  curPos keeps track of
  271. //   the current index into data, as it always has.  tdCurPos tracks the
  272. //   cursor within the outView mask.  Except in a few cases (such as when a
  273. //   selection is made), the cursor should never appear under a non-MASK_CHAR.
  274. //--------------------------------------------------------------------------
  275. #define   modeSelMinus  0  //* JDP 07/13/92 added SelMinus, SelPlus mnemonics
  276. #define   modeSelPlus   1
  277. #define   modeSelEnd    2  // JDP added mode flags 01/19/92
  278. #define   modeSelAll    3
  279. #define   modeSelFwd    4
  280. #define   modeSelBak    5
  281.  
  282. void near  TDataEntry::setViewPos(ushort mode)
  283. {
  284.   ushort  inc;
  285.   int     i;
  286.  
  287.   if ( mode < modeSelEnd )
  288.   { // find next writable position
  289.     tdCurPos += (inc = (mode) ? 1 : -1);
  290.     for ( i = tdCurPos;
  291.           (i > firstPos) && (i < tdLastPos) && (mask[tdCurPos] != MASK_CHAR);
  292.           i += inc )
  293.       tdCurPos += inc;
  294.   }
  295.   else switch ( mode )
  296.   {
  297.     case modeSelEnd:               // find end of data
  298.     case modeSelAll:
  299.       tdCurPos = firstPos;
  300.       for ( i = 0; data[i++] != EOS && tdCurPos <= tdLastPos; )
  301.       {                     //* JDP 07/13/92 ----^ added =
  302.         tdCurPos++;
  303.         while ( mask[tdCurPos] != MASK_CHAR )
  304.           tdCurPos++;
  305.       }
  306.       if ( mode == modeSelAll )
  307.         tdSelEnd = tdCurPos;   //* JDP 07/13/92 removed + (i >= maxLen) ? 1 : 0;
  308.       break;
  309.  
  310.     case modeSelFwd:
  311.     case modeSelBak:
  312.       // Here, find correct outView and data start/end. First, find diff.
  313.       //  betw. tdSelStart, tdSelEnd and copy that portion of outView into a
  314.       //  temp. string.  Then, bump tdSelStart until we find the next
  315.       //  MASK_CHAR pos. and adjust tdSelEnd.  Then, find selStart correspond-
  316.       //  ing to the new tdSelStart.  If selection (tdSelEnd - tdSelStart)
  317.       //  is <= 1 OR the temp. string has nothing but non-mask char's in it,
  318.       //  then nothing's been selected (might just have been a relocation by
  319.       //  mouse): reset all and set new curPos to selStart.  All this work
  320.       //  must be done even when there's no selection because we need to
  321.       //  find the new curPos relative to the new outView position.
  322.       // Otherwise, assuming something is selected, find selEnd correspond-
  323.       //  ing to tdSelEnd, then adjust curPos and tdCurPos.
  324.  
  325.       i = tdSelEnd - tdSelStart;
  326.       char *tmp = new char[i + 1];
  327.       memcpy(tmp, mask + tdSelStart, i);
  328.       tmp[i] = EOS;
  329.       for ( i = 0; mask[tdSelStart] != MASK_CHAR; ++tdSelStart, i++);
  330.       if ( tdSelEnd > tdLastPos )
  331.         tdSelEnd = tdLastPos + 1;
  332.       else
  333.         while ( mask[tdSelEnd - 1] != MASK_CHAR ) --tdSelEnd;
  334.       for ( i = 0, selStart = 0; i < tdSelStart && selStart < strlen(data); )
  335.         if ( mask[i++] == MASK_CHAR ) selStart++;
  336.       selEnd = selStart;
  337.       if ( tdSelEnd - tdSelStart < 1 || strchr(tmp, MASK_CHAR) == NULL )
  338.       {                           //* JDP 07/13/92 removed <= 1
  339.         tdCurPos   = tdSelStart;
  340.         tdSelStart = tdSelEnd = firstPos;
  341.         curPos     = selStart;
  342.         selStart   = selEnd = 0;
  343.       }
  344.       else
  345.       {
  346.         for ( ; i < tdSelEnd && selEnd < strlen(data); )
  347.           if ( mask[i++] == MASK_CHAR ) selEnd++;
  348.         tdCurPos = (mode == modeSelFwd) ? tdSelEnd /* - 1 */ : tdSelStart;
  349.         curPos   = (mode == modeSelBak) ? //* JDP 07/13/92 REMOVED || selEnd - selStart <= 1 ) ?
  350.                     selStart : selEnd;    //* JDP 07/13/92 WAS SelEnd - 1;
  351.       }
  352.       delete tmp;
  353.  
  354.   }  // END ...switch(mode)...
  355.  
  356.   if ( tdCurPos < firstPos ) tdCurPos = firstPos;          // check limits
  357.   else if ( tdCurPos > tdLastPos  ) tdCurPos = tdLastPos;
  358. }
  359.  
  360. //--------------------------------------------------------------------------
  361. //
  362. // **** TDataEntry::formatView()
  363. //
  364. //  Places the data into the outView; it's called prior to drawView() only
  365. //  when the data has been changed.  ** WRONG: called every draw()
  366. //--------------------------------------------------------------------------
  367. void near TDataEntry::formatView()
  368. {
  369.   int  maskPos = 0, dataPos = 0, dataLen = strlen(data);
  370.  
  371.   while ( maskPos < strlen(mask) )
  372.   {
  373.     if ( mask[maskPos] != MASK_CHAR )      // if NOT MASK_CHAR
  374.       outView[maskPos] = mask[maskPos];    //  insert literal
  375.     else if ( dataPos < dataLen )
  376.     {                                      // else if not past dataLen
  377.       if ( (localMode & tdlSecure ) != 0 )
  378.         outView[maskPos] = secureChar;
  379.       else
  380.         outView[maskPos] = data[dataPos];
  381.       ++dataPos;
  382.     }
  383.     else                                   // else
  384.       outView[maskPos] = ' ';              //  insert space
  385.     ++maskPos;
  386.   }
  387.   outView[maskPos] = EOS;                  // button up
  388. }
  389.  
  390. //--------------------------------------------------------------------------
  391. //
  392. // **** TDataEntry::handleEvent()
  393. //
  394. //--------------------------------------------------------------------------
  395. void  TDataEntry::handleEvent( TEvent& event )
  396. {
  397.   TView::handleEvent(event);
  398.  
  399.   int anchor, i;
  400.  
  401.   if ( event.what == evBroadcast )    //**** && owner == event.message.infoPtr )
  402.   {
  403.     switch ( event.message.command )
  404.     {
  405.       case cmTDQueryValid:
  406.         if ( !validData(NULL, NULL) )
  407.           clearEvent(event);
  408.         return;
  409.       case cmTDQueryChanged:
  410.         if ( strcmp(origData, data) != 0 )
  411.           clearEvent(event);
  412.         return;
  413.       case cmTDGotoNumber:
  414.         if ( localID == *(uchar *)event.message.infoPtr )
  415.           clearEvent(event);
  416.         return;
  417.       case cmTDResetData:
  418.         strcpy( origData, data );
  419.         return;
  420.       case cmTDGotoName:
  421.         if ( strcmp( fieldName, (char *)event.message.infoPtr ) == 0 )
  422.           clearEvent(event);
  423.         return;
  424.       default:
  425.         TInputLine::handleEvent(event);
  426.     }
  427.   }
  428.  
  429.   if( (state & sfSelected) != 0 )
  430.     switch( event.what )
  431.     {
  432.       case  evMouseDown:
  433.         if (event.mouse.doubleClick)
  434.           selectAll(True);
  435.         else
  436.         {
  437.           ushort dir = modeSelFwd;
  438.           setViewPos(modeSelAll);         // Get max. allowable selection
  439.           i = tdSelEnd;                   //  and store in i.  Get anchor
  440.           anchor = mousePos(event);       //  and make sure anchor <= i.
  441.           if ( anchor > i ) anchor = i;   // In 'do' loop, make sure i is
  442.           do                              //  not exceeded.
  443.           {
  444.             tdCurPos = mousePos(event);
  445.             if ( tdCurPos > i ) tdCurPos = i;
  446.             if( tdCurPos < anchor )
  447.             {
  448.               tdSelStart = tdCurPos;
  449.               tdSelEnd   = anchor;  // + 1;  // JDP 01/21/92 + 1
  450.               dir = modeSelBak;
  451.             }
  452.             else
  453.             {
  454.               tdSelStart = anchor;
  455.               tdSelEnd   = tdCurPos;  // + 1;  // JDP 01/21/92 + 1
  456.               dir = modeSelFwd;
  457.             }
  458.             drawView();
  459.           } while (mouseEvent(event, evMouseMove | evMouseAuto));
  460.  
  461.           setViewPos(dir);
  462.           drawView();
  463.         }
  464.         clearEvent(event);
  465.         break;
  466.  
  467.       case  evKeyDown:
  468.         switch( ctrlToArrow(event.keyDown.keyCode) )
  469.         {
  470.           case kbEsc:  // Pass on
  471.             return;
  472.  
  473.           case kbEnter:    // Is ENTER treated like tab?
  474.             if ( (globalMode & tdgEnterIsTab) )
  475.             {
  476.               event.keyDown.keyCode = kbTab;
  477.             }
  478.             else
  479.               return;       // RETURN regardless of whether we handled it ourselves
  480.           case kbTab:       // If validation enabled, is data valid?
  481.           case kbShiftTab:
  482.             if ( !(globalMode & tdgValidNow) || validData(NULL, NULL) )
  483.             {
  484.               TInputLine::handleEvent(event);
  485.               return;
  486.             }
  487.             break;
  488.  
  489.           // kbUp/kbDown:  Is up/down enabled?  Is immediate validation set?
  490.           //  If so, is up/down validation set and data valid?  If so, reset
  491.           //  keycode to TAB/SHFT-TAB and let base handle.
  492.           case kbUp:
  493.           case kbDown:
  494.             if ( (globalMode & tdgUpDownEnable) )
  495.             {
  496.               if ( (globalMode & tdgValidNow) &&
  497.                   ((globalMode & tdgValidUpDown) && !validData(NULL,NULL)) )
  498.                  break;  // return;
  499.               event.keyDown.keyCode =
  500.                 (event.keyDown.keyCode == kbUp) ? kbShiftTab : kbTab;
  501.               TInputLine::handleEvent(event);
  502.               return; // JDP 01/19/92 added here instead of below
  503.             }
  504.             break;    // JDP 01/19/92 WAS return;
  505.  
  506.           case kbLeft:          // Are arrow keys enabled?
  507.             if ( curPos > 0 && (localMode & tdlRLArrows) )
  508.             {
  509.               curPos--;
  510.               setViewPos(modeSelMinus);
  511.             }
  512.             break;
  513.  
  514.           case kbRight:                    // Are arrow keys enabled?
  515.             if ( curPos < strlen(data) && (localMode & tdlRLArrows) )
  516.             {
  517.               curPos = (curPos + 1 < maxLen) ? ++curPos : maxLen - 1;
  518.               setViewPos(modeSelPlus);
  519.               // formatView();  // JDP added 1/18, deleted 1/27
  520.             }
  521.             break;
  522.  
  523.           case kbHome:
  524.             curPos =  0;
  525.             tdCurPos = firstPos;
  526.             break;
  527.  
  528.           case kbEnd:                            // JDP 01/19 moved code to
  529.             i = strlen(data);                    //  setViewPos()
  530.             curPos = (i < maxLen) ? i : maxLen - 1;
  531.             setViewPos(modeSelEnd);
  532.             break;
  533.  
  534.           case kbBack:
  535.             if( curPos > 0 )
  536.             {
  537.               strcpy( data + curPos - 1, data+curPos );
  538.               curPos--;
  539.               setViewPos(modeSelMinus);
  540.               // formatView();  // JDP added 1/18, deleted 06/02/92
  541.             }
  542.             break;
  543.  
  544.           case kbDel:
  545.             if( selStart == selEnd )
  546.               if( curPos < strlen(data) )
  547.               {
  548.                 selStart = curPos;
  549.                 tdSelStart = tdCurPos;  // JDP 01/19/92
  550.                 selEnd = curPos + 1;
  551.               }
  552.             deleteSelect();
  553.             break;
  554.  
  555.           case kbIns:         // Is insert enabled?
  556.             if ( (localMode & tdlInsertEnable) )
  557.               setState(sfCursorIns, Boolean(!(state & sfCursorIns)));
  558.             break;
  559.  
  560.           default:
  561.             if( validKey(&event.keyDown.charScan.charCode) )
  562.             {
  563.               if( (state & sfCursorIns) != 0 )
  564.               {
  565.                 if ( curPos == strlen(data) )   // JDP
  566.                   *(data + curPos + 1) = EOS;
  567.                 else
  568.                   strcpy( data + curPos, data + curPos + 1 );
  569.               }
  570.               else
  571.                 deleteSelect();
  572.               if( strlen(data) < maxLen )
  573.               {
  574.                 memmove( data + curPos + 1, data + curPos,
  575.                          strlen(data+curPos)+1 );
  576.                 data[curPos++] = event.keyDown.charScan.charCode;
  577.                 if ( curPos >= maxLen )
  578.                 {
  579.                   curPos = maxLen - 1;
  580.                   if ( (localMode & tdlAutoExit) != 0 )
  581.                     exitAuto = True;
  582.                 }
  583.                 setViewPos(modeSelPlus);
  584.               }
  585.               else                  //* JDP 07/13/92
  586.               {                     //*  Added 'beep' logic when user tries
  587.                 cout << (char)7;    //*  to insert in a full field.
  588.                 clearEvent(event);
  589.                 return;
  590.               }
  591.               // formatView();  // JDP added 1/18, deleted 06/02/92
  592.             }
  593.             else if ( event.keyDown.charScan.charCode == kbCtrlR )
  594.             {
  595.               if ( strlen(origData) && strcmp(data, origData) != 0 )
  596.                 strcpy( data, origData );    // Restore original data
  597.               else
  598.               {
  599.                 clearEvent(event);
  600.                 return;
  601.               }
  602.             }
  603.             else if( event.keyDown.charScan.charCode == CONTROL_Y)
  604.             {
  605.               *data = EOS;
  606.               curPos = 0;
  607.               tdCurPos = firstPos;
  608.               // formatView();  // JDP added 1/18, deleted 06/92/92
  609.             }
  610.             else
  611.             {
  612.               if ( (globalMode & tdgBeepEnable) )  cout << (char) 7;
  613.               clearEvent(event);  //* JDP 07/13/92 ADDED so ofPostProcess
  614.               return;             //*  fields don't grab the keystroke!
  615.             }
  616.         }
  617.       selStart = selEnd = 0;
  618.       tdSelStart = tdSelEnd = firstPos;
  619.       drawView();
  620.       clearEvent( event );
  621.       if ( exitAuto )
  622.       {
  623.         exitAuto = False;
  624.         if ( (globalMode & tdgValidNow) == 0 || validData(NULL, NULL) )
  625.           owner->selectNext(False);
  626.       }
  627.       break;
  628.  
  629.     }  // END ...if (state && sfSelected...)
  630. }
  631.  
  632. //--------------------------------------------------------------------------
  633. //
  634. // **** TDataEntry::selectAll()
  635. //
  636. //--------------------------------------------------------------------------
  637. void TDataEntry::selectAll( Boolean enable )
  638. {
  639.   selStart = 0;
  640.   tdSelStart = firstPos;
  641.   if( enable )
  642.   {
  643.     curPos = selEnd = strlen(data);
  644.     if ( curPos >= maxLen ) --curPos;  // JDP 01/19/92
  645.     setViewPos(modeSelAll);
  646.   }
  647.   else
  648.   {
  649.     selEnd = 0;                        // JDP 01/19 WAS curPos = selEnd = 0;
  650.     tdSelStart = tdSelEnd = firstPos;  // JDP 01/19/92
  651.   }
  652.   drawView();
  653. }
  654.  
  655. //--------------------------------------------------------------------------
  656. //
  657. // **** TDataEntry::setData()
  658. //
  659. //--------------------------------------------------------------------------
  660. void TDataEntry::setData( void *rec )
  661. {
  662.   memcpy( data, rec, dataSize()-1 );
  663.   data[dataSize()-1] = EOS;
  664.   strcpy(origData, data);
  665.   tdSelStart = tdSelEnd = curPos = 0;  // JDP 06/23/92 added curPos = 0
  666.   tdCurPos = firstPos;
  667.   // formatView();        // JDP added 1/27/92
  668.   // selectAll( True ); // JDP 02/02/92
  669. }
  670.  
  671. //--------------------------------------------------------------------------
  672. //
  673. // **** TDataEntry::setState()
  674. //
  675. //--------------------------------------------------------------------------
  676. void TDataEntry::setState( ushort aState, Boolean enable )
  677. {
  678.   TView::setState( aState, enable );
  679.   if( aState == sfSelected ||
  680.       ( aState == sfActive && (state & sfSelected) != 0 ) )
  681.      if ( (globalMode & tdgSelectOnFocus) )  // JDP 01/19 !enable ||
  682.        selectAll( enable );
  683. }
  684.  
  685. //--------------------------------------------------------------------------
  686. //
  687. // **** TDataEntry::validData()
  688. //
  689. //--------------------------------------------------------------------------
  690. Boolean TDataEntry::validData( const char *iMsg, const char *rMsg) // JDP 05/30/92
  691. {
  692.   if ( strlen(data) )
  693.   {
  694.     for ( char *p = data; *p != EOS; p++ )
  695.       if ( !validKey((uchar *)p) )
  696.       {
  697.         const char *msg = ( iMsg ) ? iMsg : msgDataInvalid;
  698.         if ( (globalMode & tdgBeepEnable) != 0 ) cout << (char)7;
  699.         if ( msg ) messageBox( msg, mfError|mfOKButton );
  700.         select();
  701.         return False;
  702.       }
  703.   }
  704.   else if ( (localMode & tdlRequired) != 0 )
  705.   {
  706.     const char *msg = ( rMsg ) ? rMsg : msgDataRequired;
  707.     if ( (globalMode & tdgBeepEnable) != 0 ) cout << (char)7;
  708.     if ( msg ) messageBox( msg, mfError|mfOKButton );
  709.     select(); return False;
  710.   }
  711.   return True;
  712. }
  713.  
  714. //--------------------------------------------------------------------------
  715. //
  716. // **** TDataEntry::valid()
  717. //
  718. //--------------------------------------------------------------------------
  719. Boolean TDataEntry::valid(ushort cmd)
  720. {
  721.   if ( (cmd == cmValid) &&
  722.        (data == NULL || mask == NULL || outView == NULL || origData == NULL)
  723.      )
  724.   {
  725.     return False;
  726.   }
  727.   return True;
  728. }
  729.  
  730. //--------------------------------------------------------------------------
  731. //
  732. // **** TDataEntry::locateID()
  733. //
  734. //--------------------------------------------------------------------------
  735. TDataEntry *TDataEntry::locateID( TView *fieldOwner, uchar fieldNumber,
  736.                                          Boolean select )
  737. {
  738.   uchar i = fieldNumber;
  739.   TDataEntry *field =
  740.     (TDataEntry *)message( fieldOwner, evBroadcast, cmTDGotoNumber, &i );
  741.   if ( field && select ) field->select();
  742.   return field;
  743. }
  744.  
  745. //--------------------------------------------------------------------------
  746. //
  747. // **** TDataEntry::locateName()
  748. //
  749. //--------------------------------------------------------------------------
  750. TDataEntry *TDataEntry::locateName( TView *fieldOwner, const char *fName,
  751.                                            Boolean select )
  752. {
  753.   TDataEntry *field =
  754.     (TDataEntry *)message( fieldOwner, evBroadcast, cmTDGotoName, (void *)fName );
  755.   if ( field && select ) field->select();
  756.   return field;
  757. };
  758.  
  759. //--------------------------------------------------------------------------
  760. //
  761. // **** TDataEntry::resetData()
  762. //
  763. //--------------------------------------------------------------------------
  764. void TDataEntry::resetData( TView *fieldOwner, TDataEntry *target )
  765. {
  766.   message( (target == NULL) ? fieldOwner : target,
  767.            evBroadcast, cmTDResetData, fieldOwner );
  768. };
  769.  
  770. //--------------------------------------------------------------------------
  771. //
  772. // **** TDataEntry::queryChanged()
  773. //
  774. //--------------------------------------------------------------------------
  775. TDataEntry *TDataEntry::queryChanged( TView *fieldOwner, TDataEntry *target )
  776. {
  777.   TDataEntry *field =
  778.     (TDataEntry *)message( (target == NULL) ? fieldOwner : target,
  779.                            evBroadcast, cmTDQueryChanged, fieldOwner );
  780.   return field;
  781. };
  782.  
  783. //--------------------------------------------------------------------------
  784. //
  785. // **** TDataEntry::queryValid()
  786. //
  787. //--------------------------------------------------------------------------
  788. TDataEntry *TDataEntry::queryValid( TView *fieldOwner, TDataEntry *target )
  789. {
  790.   TDataEntry *field =
  791.     (TDataEntry *)message( (target == NULL) ? fieldOwner : target,
  792.                            evBroadcast, cmTDQueryValid, fieldOwner );
  793.   return field;
  794. };
  795.  
  796.